昨天快的說完我在在使用DTO 時帶給我們的好處,今天的話要來說說為甚麼在寫Web 時會用到非同步
當客戶端向我們的API 發送請求時,ASP.NET Core 會從線程池中分配線程來處理該請求。所以以下圖為例,當我前兩的Request 的要求佔到現成後第三個任務要等前兩個任務都完成才能繼續做下去
由於任務是可以等待的,所以客戶端哪一定會遇到減速的問題。但是當等待過久就可能遇到服務不可用的問題(503)。再加上當任務多起來的話,會造成任務上的阻塞,任務無法進行都在等待的問題,所以同步的方式也不太常會拿來使用
當現在我們使用非同步的話,每項客戶端的任務送到數據庫時,通常都會在3秒後開始回傳給API 端,而不向同步要等全部的任務完成才會回傳
這意味著我們可以處理更多的請求,我們不會阻塞我們的線程,並且我們不會強制線程等待(並且什麼都不做)三秒鐘直到數據庫完成它的工作。所有這些都提高了我們應用程序的可擴展性
在使用非同步時我們通常一定會使用到async和await,來達到非同步的功能,
如果但使用async 沒用await 的話功能還是跟同不一樣,所以要記得它們兩的是不可分割的一部分
它做的第一件事是檢查操作是否已經完成。如果是,它將繼續同步執行方法。否則, await 關鍵字將暫停異步方法的執行並返回一個不完整的任務。一旦操作完成,幾秒鐘後,異步方法可以繼續執行
void
void 返回類型可用於需要 void 返回類型的異步事件處理程序
public async void SaveDataAsync(Employee employee)
{
_dbcontext.Employees.Add(employee);
await _dbcontext.SaveChanges();
}
Task
當異步方法不包含返回語句或包含不返回操作數的返回語句時使用任務
public async Task SaveDataAsync(Employee employee)
{
_dbcontext.Employees.Add(employee);
await _dbcontext.SaveChanges();
}
Task
當異步方法包含返回操作數的返回語句時使用 Task
public async Task<bool> SaveDataAsync(Employee employee)
{
_dbcontext.Employees.Add(employee);
await _dbcontext.SaveChanges();
return true;
}
ValueTask
異步方法可以返回具有可訪問 GetAwaiter 方法的任何類型,該方法返回等待器類型的實例
public async ValueTask<bool> SaveDataAsync(Employee employee)
{
_dbcontext.Employees.Add(employee);
await _dbcontext.SaveChanges();
return true;
}
IAsyncEnumerable
從 C# 8.0 開始,異步方法可以返回異步流,由 IAsyncEnumerable 表示。異步流提供了一種在重複異步調用以塊的形式生成元素時枚舉從流中讀取的項目的方法
今天界介紹了非同步在.NET 上的使用愈注意細節,說實話其實還有很多細節沒說道但希望大家可以接受今天的內容,那今天的鐵人賽就到這裡啦~~~
參考資料: